<?php
# MantisBT - a php based bugtracking system

# MantisBT is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# MantisBT is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with MantisBT.  If not, see <http://www.gnu.org/licenses/>.

/**
 * @author Author Bernard de Rubinat - bernard@derubinat.net
 * Inspired from Kenzaburo Ito 's bug_relationship_graph_img.php
 */


/**            
 * MantisBT Core API's         
 */            
require_once( 'core.php' );

require_once( 'bug_api.php' );
require_once( 'compress_api.php' );
require_once( 'current_user_api.php' );

/**            
 * Graphviz API
 */            
require_once( 'graphviz_api.php' );


# If relationship graphs were made disabled, we disallow any access to this script.                  
# BDR FIXME maybe workflow graphs should be displayed anyway
        auth_ensure_user_authenticated();       
                                                
        if ( ON != config_get( 'relationship_graph_enable' ) )
                access_denied();

        compress_enable();

        $t_access = current_user_get_access_level();


# Has graph transition
function has_graph_transition( $p_from_status_id, $p_to_status_id ) {
	$t_project_workflow = parse_workflow( config_get( 'status_enum_workflow' ) );

	if ( $p_from_status_id <> $p_to_status_id ) {
		$t_project = isset( $t_project_workflow['exit'][$p_from_status_id][$p_to_status_id] ) ? 1 : 0;

		$t_flag = ( 1 == $t_project );
                $t_label = $t_flag ? $t_project_workflow['exit'][$p_from_status_id][$p_to_status_id] : '';

		if ($t_flag) {
			return 1;
		} else {
			return 0;
		}
	}
}

function display_workflow_graph() {

	$t_status_arr  = MantisEnum::getAssocArrayIndexedByValues( config_get( 'status_enum_string' ) );

        $t_graph_fontname = config_get( 'relationship_graph_fontname' );
        $t_graph_fontsize = config_get( 'relationship_graph_fontsize' );
        $t_graph_fontpath = get_font_path();
        $t_neato_tool = config_get( 'neato_tool' );

        $t_graph_attributes = array();

        if( !empty( $t_graph_fontpath ) ) {
                $t_graph_attributes['fontpath'] = $t_graph_fontpath;
        }

        $t_graph = new Graph( 'workflow', $t_graph_attributes, $t_neato_tool );

        $t_graph->set_default_node_attr( array (
                        'fontname'      => $t_graph_fontname,
                        'fontsize'      => $t_graph_fontsize,
                        'shape'         => 'record',
                        'style'         => 'filled',
                        'height'        => '0.2',
                        'width'         => '0.4'
        ) );

        $t_graph->set_default_edge_attr( array (
                        'style'         => 'solid',
                        'color'         => '#0000C0',
                        'dir'           => 'forward'
        ) );

	foreach ( $t_status_arr as $t_from_status => $t_from_label) {
		$t_enum_status = MantisEnum::getAssocArrayIndexedByValues( config_get( 'status_enum_string' ) );
		foreach ( $t_enum_status as $t_to_status_id => $t_to_status_label ) {
			if ( has_graph_transition( $t_from_status, $t_to_status_id ) ) {
				$t_graph->add_edge(
					string_no_break( MantisEnum::getLabel( lang_get( 'status_enum_string' ), $t_from_status ) ),
					string_no_break( MantisEnum::getLabel( lang_get( 'status_enum_string' ), $t_to_status_id ) ) ,
					array() );
			}
		}
	}

       	$t_graph->output( 'png', true );

}

display_workflow_graph();

# [BDR] FIXME BAD PROGRAMMING. This is a copy from manage_config_workflow_graph.php
# The function should be moved to an include
        function parse_workflow( $p_enum_workflow ) {
        $t_status_arr  = MantisEnum::getAssocArrayIndexedByValues( config_get( 'status_enum_string' ) );
        if ( 0 == count( $p_enum_workflow ) ) {
            # workflow is not set, default it to all transitions
                foreach ( $t_status_arr as $t_status => $t_label ) {
                        $t_temp_workflow = array();
                            foreach ( $t_status_arr as $t_next => $t_next_label ) {
                                    if ( $t_status <> $t_next ) {
                                       $t_temp_workflow[] = $t_next . ':' . $t_next_label;
                                    }
                            }
                        $p_enum_workflow[$t_status] = implode( ',', $t_temp_workflow );
                    }
            }

        $t_entry = array();
        $t_exit = array();

        # prepopulate new bug state (bugs go from nothing to here)
        $t_submit_status_array = config_get( 'bug_submit_status' );
                $t_new_label = MantisEnum::getLabel( lang_get( 'status_enum_string' ), config_get( 'bug_submit_status' ) );
        if ( is_array( $t_submit_status_array ) ) {
                # @@@ (thraxisp) this is not implemented in bug_api.php
                foreach ($t_submit_status_array as $t_access => $t_status ) {
                        $t_entry[$t_status][0] = $t_new_label;
                        $t_exit[0][$t_status] = $t_new_label;
                }
        } else {
                        $t_status = $t_submit_status_array;
                        $t_entry[$t_status][0] = $t_new_label;
                        $t_exit[0][$t_status] = $t_new_label;
        }

        # add user defined arcs and implicit reopen arcs
        $t_reopen = config_get( 'bug_reopen_status' );
                $t_reopen_label = MantisEnum::getLabel( lang_get( 'resolution_enum_string' ), config_get( 'bug_reopen_resolution' ) );
        $t_resolved_status = config_get( 'bug_resolved_status_threshold' );
        $t_default = array();
        foreach ( $t_status_arr as $t_status => $t_status_label ) {
                if ( isset( $p_enum_workflow[$t_status] ) ) {
                        $t_next_arr = MantisEnum::getAssocArrayIndexedByValues( $p_enum_workflow[$t_status] );
                        foreach ( $t_next_arr as $t_next => $t_next_label) {
                    if ( !isset( $t_default[$t_status] ) ) {
                        $t_default[$t_status] = $t_next;
                    }
                                        $t_exit[$t_status][$t_next] = '';
                                        $t_entry[$t_next][$t_status] = '';
                                }
                } else {
                        $t_exit[$t_status] = array();
                }
                if ( $t_status >= $t_resolved_status ) {
                        $t_exit[$t_status][$t_reopen] = $t_reopen_label;
                        $t_entry[$t_reopen][$t_status] = $t_reopen_label;
                }
                if ( !isset( $t_entry[$t_status] ) ) {
                        $t_entry[$t_status] = array();
                }
        }
        return array( 'entry' => $t_entry, 'exit' => $t_exit, 'default' => $t_default );
    }




